﻿// <copyright file="PlayerCheckers.cs" company="ALCPU">
// Copyright (c) 2010 All Right Reserved
// </copyright>
// <author>Arthur Liberman</author>
// <email>Arthur_Liberman@hotmail.com</email>
// <date>04-04-2010</date>
// <summary>Contains DoubleIndexedProperty class definition.</summary>

namespace Chess.Checkers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Input;
    using ChessDefinitions;

    /// <summary>
    /// The PlayerCheckers class, defines a Checkers game routines.
    /// </summary>
    public class PlayerCheckers : PlayerBase
    {
        /// <summary>
        /// The gameboard.
        /// </summary>
        private Gameboard gameboard;

        /// <summary>
        /// The currently selected piece.
        /// </summary>
        private IPiece selectedPiece;

        /// <summary>
        /// Counts the number of moves in each turn.
        /// </summary>
        private int moveCounter;

        /// <summary>
        /// Initializes a new instance of the <see cref="PlayerCheckers"/> class.
        /// </summary>
        /// <param name="color">The piece color.</param>
        /// <param name="gameboard">The gameboard.</param>
        public PlayerCheckers(IPieceColor color, Gameboard gameboard) : base(color)
        {
            IPiece newPiece;
            int offset = 0, startPos = 0;

            this.gameboard = gameboard;
            this.moveCounter = 0;
            this.selectedPiece = null;

            if (color == IPieceColor.White)
            {
                offset = 5;
                startPos = 1;
            }
            else if (color == IPieceColor.Black)
            {
                offset = 0;
                startPos = 0;
            }

            for (int j = 0; j < 3; j++)
            {
                startPos = (++startPos) % 2;
                for (int i = startPos; i < 8; i += 2)
                {
                    newPiece = new Man(color, gameboard, new Position(i, j + offset));
                    newPiece.GameEvent += new PieceEvent(this.Piece_GameEvent);
                    this.PieceList.Add(newPiece);
                }
            }
        }

        /// <summary>
        /// Prevents a default instance of the <see cref="PlayerCheckers"/> class from being created.
        /// </summary>
        private PlayerCheckers() : base(0)
        {
        }

        /// <summary>
        /// Starts the turn.
        /// </summary>
        public override void StartTurn()
        {
            this.moveCounter = 0;
            this.selectedPiece = null;
            this.IsTurnActive = true;
        }

        /// <summary>
        /// Ends the current turn.
        /// </summary>
        public override void EndTurn()
        {
            this.IsTurnActive = false;
            this.selectedPiece = null;
            this.gameboard.RecolorGameboard();
            this.NotifyOfGameEvent(this, GameEventType.TurnEnded);
        }

        /// <summary>
        /// Handles the user input.
        /// </summary>
        /// <param name="eventArgs">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public override void HandleUserInput(EventArgs eventArgs)
        {
            if (eventArgs == null || !(eventArgs is MouseButtonEventArgs))
            {
                throw new Exception("User input handling error, eventArgs is null or no MouseButtonEventArgs");
            }
            else if (!this.IsTurnActive)
            {
                return;
            }

            MouseButtonEventArgs mouseArgs = eventArgs as MouseButtonEventArgs;
            Position position = this.gameboard.GetMousePosition(mouseArgs);
            IPiece piece = this.gameboard.GetFigureByPosition(position);

            if (mouseArgs.RightButton == MouseButtonState.Pressed)
            {
                if (this.moveCounter == 0)
                {
                    this.selectedPiece = null;
                    this.gameboard.RecolorGameboard();
                }
                else
                {
                    this.EndTurn();
                }

                return;
            }
            else if (piece != null && piece == this.selectedPiece)
            {
                return;
            }

            if (this.moveCounter == 0 && piece != null && piece.Color == this.Color &&
                (this.selectedPiece == null || this.selectedPiece != piece))
            {
                this.gameboard.RecolorGameboard();
                this.selectedPiece = piece;
                this.gameboard.ShowSelected(piece.Position);
                this.gameboard.ShowAvailable(piece);
                this.gameboard.ShowAttackable(piece);
            }
            else if (this.moveCounter == 0 && piece == null && this.selectedPiece != null &&
                this.selectedPiece.MoveOptions.Contains(position))
            {
                this.selectedPiece.MoveTo(position);
                this.NotifyOfGameEvent(this, GameEventType.Move);
                this.EndTurn();
            }
            else if (piece != null && this.selectedPiece != null && this.selectedPiece.AttackOptions.Contains(position))
            {
                if (this.selectedPiece.Attack(position))
                {
                    this.moveCounter++;
                    this.gameboard.RecolorGameboard();
                    this.gameboard.ShowAttackable(this.selectedPiece);
                    this.gameboard.ShowSelected(this.selectedPiece.Position);
                    this.NotifyOfGameEvent(this, GameEventType.Attack);
                }
                
                if (this.selectedPiece.AttackOptions.Count == 0)
                {
                    this.EndTurn();
                }
            }
        }

        /// <summary>
        /// Piece's game event handler.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="gea">The <see cref="ChessDefinitions.GameEventArgs"/> instance containing the event data.</param>
        protected void Piece_GameEvent(IPiece sender, GameEventArgs<IPiece> gea)
        {
            if (gea != null && sender != null)
            {
                switch (gea.GameEventType)
                {
                    case GameEventType.None:
                        break;
                    case GameEventType.Attack:
                        this.PieceList.Remove(sender);
                        this.gameboard.Figures[sender.Position] = null;
                        break;
                    case GameEventType.Crowned:
                        IPiece piece = new Checkers.King(sender);
                        this.PieceList.Remove(sender);
                        this.PieceList.Add(piece);
                        break;
                }
            }
        }
    }
}
